#include<iostream>
#include<string>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h> 
#include<signal.h>
using namespace std;

class Tcp_Server{

  public:
    Tcp_Server(int port)
      :_port(port)
    {}
    void InitServer()
    {
      //创建套接字
      _sockfd = socket(AF_INET,SOCK_STREAM,0);
      if(_sockfd<0)
      {
        cerr<<"socket error"<<endl;
        exit(2);
      }
      cout<<"socket success"<<endl;
      //绑定
      struct sockaddr_in local;
      memset(&local,'\0',sizeof(local));
      local.sin_family = AF_INET; 
      local.sin_port = htons(_port);
      local.sin_addr.s_addr = INADDR_ANY;
      
      if(bind(_sockfd,(struct sockaddr*)&local,sizeof(local))==-1)
      {
        cerr<<"bind fail"<<endl;
        exit(3);
      }
      cout<<"bind success"<<endl;
      //监听
      if(listen(_sockfd,10)<0)
      {
        cerr<<"listen fail"<<endl;
        exit(4);
      }  

    }

    void Service(int sock,string client_ip,int client_port)
    {
      char buf[1024];
      while(1)
      {
        ssize_t size = read(sock,buf,sizeof(buf)-1);
        if(size>0)//读取成功
        {
          buf[size]='\0';
          cout<<"get a new link->"<<sock<<" "<<"# "<<buf<<endl;
          write(sock,buf,size);
        }
        else if(size==0)//对端关闭
        {
          cout<<client_ip<<":"<<client_port<<":"<<"close"<<endl;
          break;
        }
        else 
        {
          cerr<<"读取失败"<<endl;
          break;
        }
      }
      close(sock);

    }

    void Start()
    {
      signal(SIGCHLD,SIG_IGN);
      while(1)
      {
        //获取连接
        struct sockaddr_in peer;
        memset(&peer,'\0',sizeof(peer));
        socklen_t len = sizeof(peer);
        int sock=accept(_sockfd,(struct sockaddr*)&peer,&len);
        if(sock<0)
        {
          cerr<<"accept error,continue next"<<endl;
          continue;
        }

        string client_ip = inet_ntoa(peer.sin_addr);
        int client_port = ntohs(peer.sin_port);
        cout<<"get a new link->"<<sock<<" ,"<<client_ip<<" port:"<<client_port<<endl;

        pid_t id=fork();
        if(id==0)
        {
        //子进程处理请求
       Service(sock,client_ip,client_port);
       exit(9);
        } 
       }
    }

    ~Tcp_Server()
    {
      if(_sockfd>=0)
      {
        close(_sockfd);
      }
    }


  private:
    int _sockfd;
    int _port;
};

int main(int argc,char* argv[])
{
  if(argc!=2)
  {
    cout<<"Usage: "<<argv[0]<<" port"<<endl;
    exit(1);
  }

  int port = atoi(argv[1]);
  Tcp_Server* ts = new Tcp_Server(port);
  ts->InitServer(); 
  ts->Start();
  return 0;
}
